from typing import Dict, Any, Optional
import asyncio

from langchain_core.messages import AIMessage, HumanMessage
from langgraph.constants import END
from langgraph.graph import add_messages
from app.models import SessionState, CustomEncoder
from app.utils.llm_client import LLMClient
import json

from app.utils.logger_util import user_logger


class ChangeOrNot:
    CHANGE = "change"
    NOT_CHANGE = "not_change"

message_str='''{
	"type": "",
	"message": 
		{
			"desc": "",
			"data": ""	
		}
    }'''

def require_reconfirm_extract_node(state: SessionState,config:dict) -> SessionState:
    new_state = state.copy()
    user_input = next((msg.content for msg in reversed(new_state["messages"]) if isinstance(msg, HumanMessage)), None)
    new_state["user_require"].append(user_input)
    thread_id=config.get("configurable",{}).get("thread_id")

    message_dict = json.loads(message_str)
    message_dict["type"] = "节点"
    message_dict["message"]["desc"] = "需求方案二次确认"

    #user_logger.info(thread_id, json.dumps(message_dict, ensure_ascii=False))
    filtered_state = {
        key: value for key, value in new_state.items()
        if  key  in ['field_availability']
    }
    message_dict["message"]["data"] = ("*为确保输出结果精准匹配你的需求，该函数会在生成初步结果后，主动提示你进行确认。"
                                       "你可直观反馈 “满意”，函数将直接锁定结果并完成后续流程；若需调整，"
                                       "也能清晰说明字段的修改内容，函数会基于你的反馈快速迭代优化，"
                                       "反复确认直至输出符合预期，全程保障你的需求得到充分满足，目前用户输入及需要修改的信息有："+str(filtered_state))
    #message_dict["message"]["data"] = json.dumps(filtered_state,  cls=CustomEncoder,ensure_ascii=False)
    user_logger.info(thread_id, json.dumps(message_dict, ensure_ascii=False))


    # 使用 thread_id 初始化 LLMClient，便于在模型支持时输出/记录思考
    llm_client = LLMClient(thread_id=thread_id)
    current_require_json = new_state["require_json"]
    if isinstance(current_require_json, str):
        current_require_json = json.loads(current_require_json)

    field_availability_json = new_state["field_availability"]
    unmatched_fields = []
    if field_availability_json:
        for field in field_availability_json['fields_info']:
            if field['final_match'] == "":
                unmatched_fields.append(field['original_field'])
    else:
        new_state["user_satisfaction_intention"] = "1"
        return new_state

    print("require_reconfirm_extract_node测试打印rag查询后的require_json")
    print(new_state["require_json"])
    system_prompt = f"""
你是一个数据需求字段管理助手。用户会根据目前需求满足的情况做出答复。你需要根据用户的最新输入，判断用户是否有新增字段，或是否需要删除（舍弃）某些字段，或者是否需要替换某些字段。
请严格按照如下JSON格式输出：
{{
  "require_json": {{}},  // 这是完整的需求json，只允许你修改"fields_info"列表及其中每个字段的"status"属性
  "user_satisfaction_intention": "1或0" // 0表示用户有新增字段（包括替换操作中的新增），1表示没有新增字段或用户表示满意
}}
你的任务：
1. 你会收到当前的需求字段信息（require_json）、当前无法满足需求的字段（unmatched_fields）、以及用户的最新输入。。
2. 如果用户要新增字段，请将新增字段补充到fields_info列表，并将status设为1，user_satisfaction_intention设为0。
3. 如果用户要删除（不再需要）某些字段，请将这些字段的status设为0。
4. 如果用户要替换某些字段，请将原字段的status设为0，并新增一个新字段，status设为1，并将user_satisfaction_intention设为0。
5. 如果用户输入直接删除或者都不要了，那么意味着{unmatched_fields}字段都不需要了，把它们的status设为0，user_satisfaction_intention设为1。
6. 保证新增字段的fields_info中每个字段都包含original_field、field_examples、direct_from_table、status四个key，如果field_examples、direct_from_table未输入，赋值为"未明确"。
7. 如果用户没有新增字段（且没有进行替换操作），user_satisfaction_intention设为1
8. 用户如果说满意或者接受，user_satisfaction_intention设为1。
9. 只输出上述JSON，不要输出多余内容。

【当前需求字段信息】:
{json.dumps(current_require_json, ensure_ascii=False)}

【当前无法满足需求的字段(unmatched_fields)】:
{unmatched_fields}

【用户最新输入】:
{user_input}
"""

    user_prompt = "请根据上述信息输出更新后的require_json和user_satisfaction_intention。"

    llm_result = asyncio.run(llm_client.simple_chat(user_prompt, system_prompt))

    try:
        result = json.loads(llm_result)
    except Exception:
        result = {"require_json": current_require_json, "user_satisfaction_intention": "1"}

    # 解析大模型输出
    updated_require_json = result.get("require_json", current_require_json)
    user_satisfaction_intention = result.get("user_satisfaction_intention", "1")
    print("判断用户是否满意的结果是(1是满意，0是不满意)："  + str(user_satisfaction_intention))
    
    new_state["require_json"] = updated_require_json
    new_state["user_satisfaction_intention"] = user_satisfaction_intention


    # 更新user_require（用原始输入）
    new_state["require_json"]["original_text"]+='，'+user_input
    # 更新messages
    new_state["messages"] = add_messages(state["messages"], [
        AIMessage(content="字段调整已处理，当前需求信息为：" + json.dumps(updated_require_json, ensure_ascii=False))
    ])
    print("require_reconfirm_extract_node测试打印更新后的require_json")
    print(new_state["require_json"])

    # 生成并记录思考摘要（并以统一格式写入 desc）
    try:
        think_pack = llm_client.generate_think_sync(
            purpose="用户字段变更与满意度识别",
            context={
                "user_input": user_input,
                "unmatched_fields": unmatched_fields,
                "updated_require_json": updated_require_json,
                "user_satisfaction_intention": user_satisfaction_intention,
            },
            max_tokens=220,
        )
        think_text = think_pack.get("display") if isinstance(think_pack, dict) else str(think_pack)
        message_dict = json.loads(message_str)
        message_dict["type"] = "思考"
        message_dict["message"]["desc"] = think_text
        message_dict["message"]["data"] = "字段调整摘要"
        user_logger.info(thread_id, json.dumps(message_dict, ensure_ascii=False))
    except Exception:
        try:
            message_dict = json.loads(message_str)
            message_dict["type"] = "思考"
            message_dict["message"]["desc"] = "字段调整摘要生成失败"
            message_dict["message"]["data"] = "字段调整摘要"
            user_logger.info(thread_id, json.dumps(message_dict, ensure_ascii=False))
        except Exception:
            pass

    return new_state

def require_reconfirm(field_json: str, require_json: str, llm_client: Optional[LLMClient] = None) -> Dict[str, Any]:
    """

    Output
    {
        "change_or_not": "change","not_change"
        "reconfirm_input": ???没想好
    }
    """
    result = {}
    return result
